import pandas as pd
import numpy as np
import random
from matplotlib import pyplot as plt

# 禁止未来预期报错
pd.set_option('future.no_silent_downcasting', True)

# 写你自己的文件路径！
filepath=r'D:\PYCHARM文件\zwz050418\main\house-info.csv'
df = pd.read_csv(filepath, encoding='utf-8')

print(df.info())

# 填充缺失值
df.replace('暂无',np.nan,inplace=True)
df.replace('nan',np.nan,inplace=True)
df.replace('无',np.nan,inplace=True)

# 数据格式转换
df['建筑面积'] = df['建筑面积'].astype(str).map(lambda x: x.replace('平米', '')).astype('float')
df['单价'] = df['单价'].astype(str).map(lambda x: x.replace('元/平米','')).astype('float')

def process_year(year):
    if year is not None:
        year = str(year)[:4]
    return year
df['建筑年代'] = df['建筑年代'].map(process_year)

# [' 底层 ' '中层' '顶层' '低层' '高层' '无' ' 地下 ' ' 高层 ' ' 低层 ' ' 中层 ']
floor = {' 底层 ':"低", '中层':"中", '顶层':"高", '低层' :"低",'高层' :"高",'无' :np.nan,' 地下 ' :"低",' 高层 ':"高", ' 低层 ' :"低",' 中层 ':"中"}
df['楼层'] = df['楼层'].map(floor)

def process_price(price):
    if price is not None:
        price = str(price)[:-1]
    return price
df['总价'] = df['总价'].map(process_price)

# 填充缺失值
df.replace('暂无',np.nan,inplace=True)
df.replace('nan',np.nan,inplace=True)
df.replace('无',np.nan,inplace=True)

# 处理异常值
df.replace('0年',np.nan,inplace=True)
df.replace('年',np.nan,inplace=True)
df.replace(' 暂无 ',np.nan,inplace=True)

# 重复值处理:删除重复值
df.drop_duplicates(inplace=True)
df.reset_index(drop=True, inplace=True)

# 缺失值处理
# 户型、朝向、楼层处理，缺失值数量不多，考虑直接删除即可
df.dropna(subset=['户型','朝向','楼层'], inplace=True)

# 建筑年代、建筑类别、建筑结构、住宅类别、产权性质、装修 这些离散型变量很难处理，得根据实际情况填充，为了得到更加真实的结果暂不处理
# 电梯处理（底层无，高层有，中层随机处理）
df.loc[(df['楼层'] == '高') & (df['有无电梯'].isnull()),'有无电梯'] = '有 '
df.loc[(df['楼层'] == '低') & (df['有无电梯'].isnull()),'有无电梯'] = '无 '
df.loc[(df['楼层'] == '中') & (df['有无电梯'].isnull()),'有无电梯'] = random.choice(['有 ','无 '])
df.reset_index(drop=True, inplace=True)

# 首先，确保 '总价' 列中的数据可以转换为数字
# 如果 '总价' 列中包含非数字字符串（如 '未知'、'N/A' 等），这些行需要被特别处理
df['总价'] = pd.to_numeric(df['总价'], errors='coerce')  # 将无法转换的设置为 NaN

df.to_csv(r"df-test3.csv",encoding="utf-8-sig",index=False)

# 箱线图分析
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 创建一个包含两个子图的图形
fig,ax = plt.subplots(1,2,figsize=(16,6))
# 进行数据框的箱线图绘制
df.boxplot(column=['总价'], flierprops={'markeredgecolor':'red', 'markersize':4}, ax=ax[0])
df.boxplot(column=['建筑面积'], flierprops={'markeredgecolor':'green', 'markersize':4}, ax=ax[1])
plt.show()

# 描述性分析
df.describe()
# 将高于房价600万的删除
df.drop(index = df[df['总价'] > 600].index, inplace=True)
# 另存为新Excel文件
df.to_excel('house.xlsx',index=False)